﻿
#ifndef __CONTROL_CAN_H__
#define __CONTROL_CAN_H__

/* 文件版本：v2.01 20190410 */

/* 使用CVI平台开发，请使用该语句。 */
/* #include <cvidef.h> */

/* CAN分析仪型号定义 */
#define VCI_USBCAN1     (3)
#define VCI_USBCAN2     (4)    /* USBCAN-2A  USBCAN-2C  CANalyst-II */
#define VCI_USBCAN2A    (4)

#define VCI_USBCAN_E_U     (20)
#define VCI_USBCAN_2E_U    (21)

/* 函数调用返回状态值 */
#define STATUS_OK     (1)
#define STATUS_ERR    (0)

/* 类型定义 */
typedef unsigned char     BYTE;
typedef char              CHAR;
typedef unsigned char     UCHAR;
typedef int               INT;
typedef unsigned int      UINT;
typedef unsigned short    USHORT;
typedef unsigned long     ULONG;
typedef unsigned long     DWORD;

/* C语言编译定义 */
#define EXTERNC    extern "C"

/* ==== 兼容ZLG的函数及数据类型 ==== */

/* 1. ZLGCAN系列接口卡信息的数据类型 */
struct _VCI_BOARD_INFO
{
    USHORT hw_Version;            /* 硬件版本号 */
    USHORT fw_Version;            /* 固件版本号 */
    USHORT dr_Version;            /* 驱动程序版本号 */
    USHORT in_Version;            /* 接口库版本号 */
    USHORT irq_Num;               /* 保留参数 */
    BYTE   can_Num;               /* 通道数量 */
    CHAR   str_Serial_Num[20];    /* 板卡序列号 */
    CHAR   str_hw_Type[40];       /* 硬件类型 */
    USHORT Reserved[4];           /* 系统保留 */
};
typedef struct _VCI_BOARD_INFO VCI_BOARD_INFO;
typedef struct _VCI_BOARD_INFO *PVCI_BOARD_INFO;

/* 2. 定义CAN信息帧的数据类型 */
struct _VCI_CAN_OBJ
{
    UINT ID;             /* CAN ID */
    UINT TimeStamp;      /* 时间标识 */
    BYTE TimeFlag;       /* 时间标识开关 */
    BYTE SendType;       /* 发送帧类型 */
    BYTE RemoteFlag;     /* 是否是远程帧 */
    BYTE ExternFlag;     /* 是否是扩展帧 */
    BYTE DataLen;        /* 数据长度 */
    BYTE Data[8];        /* 帧内容 */
    BYTE Reserved[3];    /* 系统保留 */
};
typedef struct _VCI_CAN_OBJ VCI_CAN_OBJ;
typedef struct _VCI_CAN_OBJ *PVCI_CAN_OBJ;

/* 3. 定义初始化CAN的数据类型 */
struct _VCI_INIT_CONFIG
{
    DWORD AccCode;     /* 验收码 */
    DWORD AccMask;     /* 屏蔽码 */
    DWORD Reserved;    /* 系统保留 */
    UCHAR Filter;      /* 滤波方式 */
    UCHAR Timing0;     /* 波特率定时器 0 */
    UCHAR Timing1;     /* 波特率定时器 1 */
    UCHAR Mode;        /* 工作模式 */
};
typedef struct _VCI_INIT_CONFIG VCI_INIT_CONFIG;
typedef struct _VCI_INIT_CONFIG *PVCI_INIT_CONFIG;

/* 4. 定义滤波类型 */
struct _VCI_FILTER_RECORD
{
    DWORD ExtFrame;    /* 扩展帧 */
    DWORD Start;       /* 开头 */
    DWORD End;         /* 结尾 */
};
typedef struct _VCI_FILTER_RECORD VCI_FILTER_RECORD;
typedef struct _VCI_FILTER_RECORD *PVCI_FILTER_RECORD;


/*

    打开设备

    一个设备只能打开一次。
    1.DeviceType 设备类型 在文件开头已经定义
    2.DeviceInd 设备索引
    3.Reserved 保留参数

*/
EXTERNC DWORD __stdcall VCI_OpenDevice(DWORD DeviceType, DWORD DeviceInd, DWORD Reserved);

/*
    关闭设备

    1. DeviceType 设备类型
    2. DeviceInd 设备索引
*/
EXTERNC DWORD __stdcall VCI_CloseDevice(DWORD DeviceType, DWORD DeviceInd);

/*
    初始化分析仪

    1. DeviceType 设备类型
    2. DeviceInd 设备索引
    3. CANInd CAN通道索引  对应CAN的通道号 CAN1 = 0  CAN2 = 1
    4. pInitConfig 要初始化的类结构
*/
EXTERNC DWORD __stdcall VCI_InitCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_INIT_CONFIG pInitConfig);

/*
    获取设备信息

    1. DeviceType 设备类型
    2. DeviceInd 设备索引
    3. pInfo 存储信息的VCI_BOARD_INFO结构体指针
*/
EXTERNC DWORD __stdcall VCI_ReadBoardInfo(DWORD DeviceType, DWORD DeviceInd, PVCI_BOARD_INFO pInfo);

/*
    设置参考值

    1. DeviceType 设备类型
    2. DeviceInd 设备索引
    3. CANInd CAN通道索引  对应CAN的通道号 CAN1 = 0  CAN2 = 1
    4. RefType 参数类型
    5. pData 参数相关数据缓冲区首地址指针
*/
EXTERNC DWORD __stdcall VCI_SetReference(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, DWORD RefType, void *pData);

/*
    获取未读帧数量

    1. DeviceType 设备类型
    2. DeviceInd 设备索引
    3. CANInd CAN通道索引  对应CAN的通道号 CAN1 = 0  CAN2 = 1
*/
EXTERNC ULONG __stdcall VCI_GetReceiveNum(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd);

/*
    清空通道缓存区

    1. DeviceType 设备类型
    2. DeviceInd 设备索引
    3. CANInd CAN通道索引  对应CAN的通道号 CAN1 = 0  CAN2 = 1
*/
EXTERNC DWORD __stdcall VCI_ClearBuffer(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd);

/*
    启动设备

    1. DeviceType 设备类型
    2. DeviceInd 设备索引
    3. CANInd CAN通道索引  对应CAN的通道号 CAN1 = 0  CAN2 = 1
*/
EXTERNC DWORD __stdcall VCI_StartCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd);

/*
    复位设备

    1. DeviceType 设备类型
    2. DeviceInd 设备索引
    3. CANInd CAN通道索引  对应CAN的通道号 CAN1 = 0  CAN2 = 1
*/
EXTERNC DWORD __stdcall VCI_ResetCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd);

/*
    发送消息

    1. DeviceType 设备类型
    2. DeviceInd 设备索引
    3. CANInd CAN通道索引  对应CAN的通道号 CAN1 = 0  CAN2 = 1
    4. pSend 发送帧结构
    5. Length 帧结构体数组的长度（发送的帧数量）。
              最大为1000，建议设为1，每次发送单帧，以提高发送效率。
*/
EXTERNC ULONG __stdcall VCI_Transmit(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_CAN_OBJ pSend, ULONG Len);

/*
    读取消息

    1. DeviceType 设备类型
    2. DeviceInd 设备索引
    3. CANInd CAN通道索引  对应CAN的通道号 CAN1 = 0  CAN2 = 1
    4. pReceive 接收的帧结构体VCI_CAN_OBJ数组的首指针。
                注意：数组的大小一定要比下面的len参数大，否则会出现内存读写错误。
    5. Len 接收的帧结构体数组的长度（本次接收的最大帧数，实际返回值小于等于这个值）
           CAN分析仪中为每个通道设置了2000帧左右的接收缓存
           pReceive数组大小与Len都设置大于2000 可有效防止数据溢出导致地址冲 2500为宜
           每隔30ms调用一次VCI_Receive为宜
    6. WaitTime 保留参数
*/
EXTERNC ULONG __stdcall VCI_Receive(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_CAN_OBJ pReceive, ULONG Len, INT WaitTime);

/*
    重启设备

    1. DevType 设备类型
    2. DevIndex 设备索引
    3. Reserved 保留
*/
EXTERNC DWORD __stdcall VCI_UsbDeviceReset(DWORD DevType, DWORD DevIndex, DWORD Reserved);

/*
    查找当前设备

    1. pInfo 结构体数组首地址
             用来存储设备序列号等信息的结构体数组
             数组长度建议定义为50
*/
EXTERNC DWORD __stdcall VCI_FindUsbDevice2(PVCI_BOARD_INFO pInfo);

#endif /* __CONTROL_CAN_H__ */
